/*
 * Created on 23 f�vr. 2005
 * nicolas.bredeche(at)lri.fr
 */

package piconode.tutorials;

import java.util.ArrayList;

import piconode.core.arc.WeightedArc;
import piconode.core.node.FeedForwardNeuralNetwork;
import piconode.core.node.Neuron;
import piconode.ext.ActivationFunction_Linear;
import piconode.ext.ActivationFunction_LogisticSigmoid;
import piconode.toolbox.Tools;

public class Tutorial_1a_simpleFeedForwardDemo {

	/**
	 * This example shows how to initialize and use a simple neural network with
	 * only feed-forwarding the signal through the net architecture.
	 */

	public static void launchExample() {

		System.out.println("This example shows how to initialize and use a simple neural network with only feed-forwarding the signal through the net architecture.");

		/* (1) Initializing and building a neural net */

		// step 1 : create a network
		FeedForwardNeuralNetwork network = new FeedForwardNeuralNetwork(true);

		// step 2 : create some neurons

		Neuron in1 = new Neuron(network, new ActivationFunction_LogisticSigmoid());
		Neuron in2 = new Neuron(network, new ActivationFunction_LogisticSigmoid());
		Neuron hidden1 = new Neuron(network, new ActivationFunction_LogisticSigmoid());
		Neuron out1 = new Neuron(network, new ActivationFunction_Linear());

		// step 3 : declare input and output neurons

		network.registerInputNeuron(in1);
		network.registerInputNeuron(in2);
		network.registerOutputNeuron(out1); // if several outputs, order is
		// important if you intend to use a
		// learning algorithm (i.e. matching
		// target and predicted values is
		// performed in list order)

		// step 4 : create the topology

		network.registerArc(new WeightedArc(in1, hidden1, Tools.getArcWeightRandomInitValue()));
		network.registerArc(new WeightedArc(in2, hidden1, Tools.getArcWeightRandomInitValue()));
		network.registerArc(new WeightedArc(hidden1, out1, Tools.getArcWeightRandomInitValue()));

		// step 5 : initialize the network (perform some integrity checks and
		// internal encoding)

		network.initNetwork();

		/* (2) using the network (feed-forward signal) */

		// step 0 : randomly initialize the weights in [0,1[ -- in fact, this
		// have been already done
		/***********************************************************************
		 * begin(optional) Environment.initializeRandomArcWeights(network);
		 * /*end(optional)
		 */

		// step 1 : loading the input values
		ArrayList inputValuesList = new ArrayList();
		inputValuesList.add(new Double(0.5));
		inputValuesList.add(new Double(0.5));

		// step 2 : computing the output values

		network.step(inputValuesList);

		System.out.println("Output value : " + out1.getValue());
	}

	/*
	 * Main
	 */

	public static void main(String[] args) {

		double startTime = System.currentTimeMillis();
		System.out.println("Running...");
		launchExample();
		System.out.println("\nTerminated (" + ((System.currentTimeMillis() - startTime) / 1000) + "s elapsed).");
	}
}
